08. Java Linker
Java Linker
ND079 JPND C3 L3 A07 Java Linker V3
JLink
JLink is a tool that allows us to create a custom Java Runtime Environment containing the minimal components necessary to run a specific Java module. This command line tool is part of the JDK, so you can run it by simply typing jlink
from any command prompt that has the Java /bin directory on the path.
Using JLink
JLink only works on modules. We'll demonstrate its use on a simple example.
App.java
import java.math.BigInteger;
import java.util.Set;
public class App
{
public static void main( String[] args )
{
Set<Integer> newSet = Set.of(1,2,3,4);
int unnecessarilyComplexSum = newSet.stream()
.map(BigInteger::valueOf)
.reduce(BigInteger.ZERO,(a, b) -> a.add(b)).intValue();
System.out.println( "Hello " + unnecessarilyComplexSum );
}
}
module-info.java
module com.udacity.jpnd.moduletest {
}
Analyze dependencies
The first step to using JLink is to make sure that all your dependencies can be resolved. The JDK includes a tool for this called jdeps. After building the above into a jar, we can run jdeps on the jar:
jdeps Example.jar
This shows us all the dependencies required by the program and where they are located.
requires mandated java.base (@14.0.1)
com.udacity.jpnd.moduletest -> java.base
com.udacity.jpnd -> java.io java.base
com.udacity.jpnd -> java.lang java.base
com.udacity.jpnd -> java.lang.invoke java.base
com.udacity.jpnd -> java.math java.base
com.udacity.jpnd -> java.util java.base
com.udacity.jpnd -> java.util.function java.base
com.udacity.jpnd -> java.util.stream java.base
Because all our dependencies are part of java.base
we can go ahead and begin linking. If your program has additional dependencies, you can use jdeps to determine whether you need to manually include additional packages in your jar.
Building Runtime
To run JLink, we must put all the required modules on the modulepath. In this case, that includes the module for our program as well as java.base. Then we use the --add-modules
flag to specify which module to add to our JRE, and lastly we provide an output directory. The modules comprising the Java Standard Library can be found in the /jmods
directory of your Java install.
jlink --module-path "$JAVA_HOME/jmods" --module-path target/classes --add-modules com.udacity.jpnd.moduletest --output tinyJRE
Using the Runtime
The new tinyJRE directory is less than 40 MB and contains a complete Java Runtime that can run our program.
tinyJRE/bin/java.exe -jar Example.jar
Resolving dependencies for projects that include non-modular dependencies can be challenging and is not covered by this introduction, but there are some Maven plugins that can assist, such as the Maven JDeps Plugin and the Moditect plugin.
Additional Resources
Building minimal JREs from larger projects can be complex. Here are some additional resources if you need to learn more about this topic.
https://docs.oracle.com/en/java/javase/15/docs/specs/man/jdeps.html
https://docs.oracle.com/en/java/javase/15/docs/specs/man/jlink.html